package com.hopes.bizz.basic.hazard.support;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hopes.bizz.basic.hazard.sds.entity.HazChemicalInEntity;
import com.hopes.bizz.basic.hazard.sds.entity.HazChemicalOutEntity;
import com.hopes.bizz.basic.hazard.sds.entity.HazChemicalStockEntity;
import com.hopes.bizz.basic.hazard.sds.entity.HazChemicalStockHisEntity;
import com.hopes.bizz.basic.hazard.sds.service.*;
import com.hopes.bizz.common.core.util.DateUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * @author daijie
 * @version 1.0
 * @date 2023/11/14 20:30
 * @Description:
 */
@RequiredArgsConstructor
@Component
public class HazChemicalSupport {

    private final HazChemicalSdsService hazChemicalSdsService;
    private final HazChemicalStockService hazChemicalStockService;
    private final HazChemicalInService hazChemicalInService;
    private final HazChemicalOutService hazChemicalOutService;
    private final HazChemicalStockHisService hazChemicalStockHisService;

    public void calculateStock(Long sdsId) {
        HazChemicalStockEntity stockEntity = hazChemicalStockService.getOne(Wrappers.lambdaQuery(HazChemicalStockEntity.class)
                .eq(HazChemicalStockEntity::getSdsId, sdsId));

        if (stockEntity == null) {
            stockEntity = new HazChemicalStockEntity();
            stockEntity.setSdsId(sdsId);
            stockEntity.setDataTime(new Date());
            stockEntity.setStockNum(BigDecimal.ZERO);
            stockEntity.setInNum(BigDecimal.ZERO);
            stockEntity.setOutNum(BigDecimal.ZERO);
            hazChemicalStockService.save(stockEntity);
        }
        // 入库总和
        BigDecimal allIn = hazChemicalInService.list(Wrappers.lambdaQuery(HazChemicalInEntity.class)
                .eq(HazChemicalInEntity::getSdsId, sdsId)).stream().map(HazChemicalInEntity::getInNumber).reduce(BigDecimal.ZERO, BigDecimal::add);
        // 出库总和
        BigDecimal allOut = hazChemicalOutService.list(Wrappers.lambdaQuery(HazChemicalOutEntity.class)
                .eq(HazChemicalOutEntity::getChemicalId, sdsId)).stream().map(HazChemicalOutEntity::getOutNumber).reduce(BigDecimal.ZERO, BigDecimal::add);

        stockEntity.setInNum(allIn);
        stockEntity.setOutNum(allOut);
        stockEntity.setStockNum(allIn.subtract(allOut));
        stockEntity.setDataTime(new Date());
        hazChemicalStockService.updateById(stockEntity);
    }

    public void calculateStockHis(Long sdsId, Date date) {
        date = DateUtils.dateLimitDay(date);
        calculateStockHisAppointDate(sdsId, date);

        long count = hazChemicalStockHisService.count(Wrappers.lambdaQuery(HazChemicalStockHisEntity.class)
                .eq(HazChemicalStockHisEntity::getSdsId, sdsId)
                .gt(HazChemicalStockHisEntity::getDataTime, date)
                .orderByDesc(HazChemicalStockHisEntity::getDataTime));
        // 说明有后续的库存变化需要更新
        if (count > 0) {
            List<HazChemicalStockHisEntity> updateList = hazChemicalStockHisService.list(Wrappers.lambdaQuery(HazChemicalStockHisEntity.class)
                    .eq(HazChemicalStockHisEntity::getSdsId, sdsId)
                    .gt(HazChemicalStockHisEntity::getDataTime, date)
                    .orderByAsc(HazChemicalStockHisEntity::getDataTime));
            for (HazChemicalStockHisEntity item : updateList) {
                calculateStockHisAppointDate(item.getSdsId(), item.getDataTime());
            }
        }
    }

    public void calculateStockHisAppointDate(Long sdsId, Date date) {
        date = DateUtils.dateLimitDay(date);
        HazChemicalStockHisEntity stockHisEntity = hazChemicalStockHisService.getOne(Wrappers.lambdaQuery(HazChemicalStockHisEntity.class)
                .eq(HazChemicalStockHisEntity::getSdsId, sdsId).eq(HazChemicalStockHisEntity::getDataTime, date));

        // 当日入库总和
        BigDecimal allIn = hazChemicalInService.list(Wrappers.lambdaQuery(HazChemicalInEntity.class)
                .eq(HazChemicalInEntity::getSdsId, sdsId).eq(HazChemicalInEntity::getInDate, date)).stream().map(HazChemicalInEntity::getInNumber).reduce(BigDecimal.ZERO, BigDecimal::add);
        // 当日出库总和
        BigDecimal allOut = hazChemicalOutService.list(Wrappers.lambdaQuery(HazChemicalOutEntity.class)
                .eq(HazChemicalOutEntity::getChemicalId, sdsId).eq(HazChemicalOutEntity::getOutDate, date)).stream().map(HazChemicalOutEntity::getOutNumber).reduce(BigDecimal.ZERO, BigDecimal::add);

        HazChemicalStockHisEntity earlier = hazChemicalStockHisService.getOne(Wrappers.lambdaQuery(HazChemicalStockHisEntity.class)
                .eq(HazChemicalStockHisEntity::getSdsId, sdsId)
                .lt(HazChemicalStockHisEntity::getDataTime, date)
                .orderByDesc(HazChemicalStockHisEntity::getDataTime)
                .last("limit 1"));
        BigDecimal earlierNum = BigDecimal.ZERO;
        if (earlier != null) {
            earlierNum = earlier.getStockNum();
        }

        if (stockHisEntity == null) {
            stockHisEntity = new HazChemicalStockHisEntity();
        }
        stockHisEntity.setSdsId(sdsId);
        stockHisEntity.setInNum(allIn);
        stockHisEntity.setOutNum(allOut);
        stockHisEntity.setStockNum(allIn.subtract(allOut).add(earlierNum));
        stockHisEntity.setDataTime(date);

        if (stockHisEntity.getId() == null) {
            hazChemicalStockHisService.save(stockHisEntity);
        } else {
            hazChemicalStockHisService.updateById(stockHisEntity);
        }
    }
}
